package daos

import (
	"context"
	"database/sql"
	"github.com/pkg/errors"
	"gocamp2022/shutdown/base"
)

/**
* CacheModel 缓存模型
 */

// CREATE TABLE `cache` (
//   `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '主键id',
//   `cache_key` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '缓存key',
//   `cache_value` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '缓存值',
//   `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
//   `modify_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
//   PRIMARY KEY (`id`),
//   KEY `idx_key` (`cache_key`) USING BTREE
// ) ENGINE=InnoDB AUTO_INCREMENT=213709 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

type CacheModel struct {
	ID         int64        `db:"id"`
	CacheKey   string       `db:"cache_key"`
	CacheValue string       `db:"cache_value"`
	CreateTime sql.NullTime `db:"create_time"`
	UpdateTime sql.NullTime `db:"update_time"`
}

type CacheDao struct {
	table string
}

func NewCacheDao() *CacheDao {
	return &CacheDao{table: "rclx.cache"}
}

func (this *CacheDao) GetOneRowByName(ctx context.Context, name string) (CacheModel, error) {
	var result CacheModel
	err := base.GetDB().GetContext(ctx, &result, "select * from "+this.table+" where name=?", name)
	return result, err
}

// InsertOneRow 插入一条记录
func (this *CacheDao) InsertOneRow(ctx context.Context, name string, value string) (int64, error) {
	result, err := base.GetDB().ExecContext(ctx, "insert into "+this.table+" (name, value) values (?, ?)", name, value)
	if err != nil {
		return 0, err
	}

	return result.LastInsertId()
}

// UpdateOneRow 更新记录
func (this *CacheDao) UpdateOneRow(ctx context.Context, id int64, name string, value string) (int64, error) {
	result, err := base.GetDB().ExecContext(ctx, "update "+this.table+" set name=?, value=? where id=?", name, value, id)
	if err != nil {
		return 0, err
	}

	return result.RowsAffected()
}

// InsertOrUpdate 插入记录，存在则更新
func (this *CacheDao) InsertOrUpdate(ctx context.Context, name, value string) error {
	var row CacheModel
	err := base.GetDB().GetContext(ctx, &row, "select id from "+this.table+" where cache_key=?", name)

	if err != nil {
		if err != sql.ErrNoRows {
			return errors.Wrap(err, "查询缓存记录失败")
		}
	}

	if row.ID > 0 {
		_, err = base.GetDB().ExecContext(ctx, "update "+this.table+" set cache_value=? where id=?", value, row.ID)
	} else {
		_, err = base.GetDB().ExecContext(ctx, "insert into "+this.table+" (cache_key, cache_value) values (?, ?)", name, value)
	}

	return err
}
